#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#define IleParametrow 12
using namespace std;


struct wine
{
	//okreslenie koloru wina 0- niezdefiniowane 1 -czerwone, 2 -biale


	enum ListaTypowKolorow{UNDEF,RED,WHITE};
	enum ListaTypowPochodzenia{RANDOM,USER,ORYGINAL};
	//okreslenie czy rekord zostal dodany przez uzytkownika,oryginalny czy losowy,
	//czy pochodzi z pierwotnej bazy danych

	ListaTypowKolorow Kolor;
	ListaTypowPochodzenia CzyjRekord;


	float atrybuty[IleParametrow];
	wine()
	{
		for (int i=0;i<IleParametrow;i++)
		{
			atrybuty[i]=0;
		}
		Kolor=UNDEF;
		CzyjRekord=RANDOM;
	}


};



class base
{
private:
	bool FileReadyToGo,BaseReady;
	wine rec;
	ifstream * odczyt;
	int AtrPrev;
	int SizePrev;
	vector<float> vec;
	vector<wine> rekordy;

public:
	string NazwaPliku;

	base()
	{
		FileReadyToGo=false;
		BaseReady=false;

	}
	bool Insert(int n,wine a)
	{
		if((n>0)&&(n<Size()))
		{
			rekordy[n]=a;
			return true;
		}
		else
		{
			return false;
		}
	}
	bool Ready()
	{
		return BaseReady;
	}

	bool Drukuj()
	{
		if (BaseReady)
		{
			for (int i=0;i<rekordy.size();i++)
			{
				for (int j=0;j<IleParametrow;j++)
				{
					cout<<rekordy[i].atrybuty[j]<<";";
				}

				switch (rekordy[i].Kolor)
				{
				case 0:
					{
						cout<<"UNDEF;";
						break;
					}
				case 1:
					{cout<<"RED;";
					break;

					}
				case 2:
					{cout<<"WHITE;";
					break;
					}
				}
				switch (rekordy[i].CzyjRekord)
				{
				case 0:
					{cout<<"RANDOM;";
					break;
					}
				case 1:
					{cout<<"USER;";
					break;

					}
				case 2:
					{cout<<"ORYGINAL;";
					break;
					}
				}
				cout<<endl;
			}
			return true;
		} 
		else
		{
			return false;
		}
	}
	bool OdczytajPlik( char * filename,wine::ListaTypowKolorow typwina)
	{
		if (filename==NULL)
		{
			FileReadyToGo=false;
			return FileReadyToGo;
		} 
		else
		{

			odczyt= new ifstream();
			this->CzyscBaze();
			BaseReady=false;
			vec.clear();
			NazwaPliku=filename;
			rec.Kolor=typwina;
			odczyt->open(filename,ifstream::in);
			rec.CzyjRekord=wine::ORYGINAL;
			FileReadyToGo=odczyt->good();
			return FileReadyToGo;
		}
	}
	void CzyscBaze()
	{

		vec.clear();
		BaseReady=false;
		FileReadyToGo=false;

		rekordy.clear();



	}
	bool UtworzBaze()
	{

		if (FileReadyToGo)
		{
			int substring_begin,substring_end;
			string temp,str;

			getline(*odczyt,str);
			while(!odczyt->eof())
			{
				getline(*odczyt,str);
				substring_end=str.find(";");
				temp=str.substr(0,substring_end);
				rec.atrybuty[0]=atof(temp.c_str());


				for (int i=1;i<IleParametrow-1;i++)
				{
					substring_begin=substring_end;
					substring_end=str.find(";",substring_begin+1);
					temp=str.substr(substring_begin+1,substring_end-substring_begin);
					rec.atrybuty[i]=atof(temp.c_str());
				}
				substring_begin=substring_end;

				temp=str.substr(substring_begin+1);
				rec.atrybuty[IleParametrow-1]=atof(temp.c_str());
				rekordy.push_back(rec);
			}
			BaseReady=true;


		} 
		else
		{
			BaseReady=false;

		}
		if (odczyt->is_open())
		{
			odczyt->close();
			odczyt->~basic_ifstream();
		}

		FileReadyToGo=false;
		return BaseReady;

	}
	int Size()
	{
		return (rekordy.size());
	}
	
	
	bool OdczytajPlik2( char * filename,wine::ListaTypowKolorow typwina)
	{
		odczyt= new ifstream();
		this->CzyscBaze();
		BaseReady=false;
		vec.clear();
		NazwaPliku=filename;
		//rec.Kolor=typwina;
		odczyt->open(filename,ifstream::in);
		//rec.CzyjRekord=wine::ORYGINAL;
		FileReadyToGo=odczyt->good();
		return FileReadyToGo;
	}


	bool UtworzBaze2()
	{

		if (FileReadyToGo)
		{
			int substring_begin,substring_end;
			string temp,str;

			getline(*odczyt,str);
			while(!odczyt->eof())
			{
				getline(*odczyt,str);
				substring_end=str.find(";");
				temp=str.substr(0,substring_end);
				rec.atrybuty[0]=atof(temp.c_str());


				for (int i=1;i<IleParametrow-1;i++)
				{
					substring_begin=substring_end;
					substring_end=str.find(";",substring_begin+1);
					temp=str.substr(substring_begin+1,substring_end-substring_begin);
					rec.atrybuty[i]=atof(temp.c_str());
				}
				substring_begin=substring_end;
				substring_end=str.find(";",substring_begin+1);

				temp=str.substr(substring_begin+1,substring_end-substring_begin);
				rec.atrybuty[IleParametrow-1]=atof(temp.c_str());
				//rekordy.push_back(rec);



				//kolor wina
				//rec.Kolor=wine::WHITE;
				//rec.CzyjRekord=wine::USER;
				substring_begin=substring_end;
				substring_end=str.find(";",substring_begin+1);

				temp=str.substr(substring_begin+1,substring_end-substring_begin);
				if(atof(temp.c_str())==0)
					rec.Kolor=wine::UNDEF;
				else
					if(atof(temp.c_str())==1)
						rec.Kolor=wine::RED;
					else
						if(atof(temp.c_str())==2)
							rec.Kolor=wine::WHITE;

				//czyj rekord
				substring_begin=substring_end;
				substring_end=str.find(";",substring_begin+1);

				temp=str.substr(substring_begin+1,substring_end-substring_begin);
				if(atof(temp.c_str())==0)
					rec.CzyjRekord=wine::RANDOM;
				else
					if(atof(temp.c_str())==1)
						rec.CzyjRekord=wine::USER;
					else
						if(atof(temp.c_str())==2)
							rec.CzyjRekord=wine::ORYGINAL;


				rekordy.push_back(rec);


			}
			BaseReady=true;


		} 
		else
		{
			BaseReady=false;

		}
		if (odczyt->is_open())
		{
			odczyt->close();
			odczyt->~basic_ifstream();
		}

		FileReadyToGo=false;
		return BaseReady;

	}

	//zapis bazy danych na dysk

	bool ZapiszNaDysku(const  char * filename)
	{
		ofstream zapis(filename);
		//zapis = new fstream();
		//zapis->open(filename,fstream::in | fstream::out | fstream::trunc);
		string str,temp;
		string myslnik = ";";
		float tmp;

		for (int i=0;i<rekordy.size()-1;i++)
		{
			string str="";

			for (int j=0;j<IleParametrow;j++)
			{
				temp="";
				char *t;
				t=new char[];
				tmp=rekordy[i].atrybuty[j];
				sprintf(t, "%f", tmp);
				temp=t;
				str.append(temp);
				str.append(myslnik);
			}

			temp="";
			if(rekordy[i].Kolor==wine::UNDEF)
				temp="0";
			else
				if(rekordy[i].Kolor==wine::RED)
					temp="1";
				else
					if(rekordy[i].Kolor==wine::WHITE)
						temp="2";
			str.append(temp);
			str.append(myslnik);

			temp="";
			if(rekordy[i].CzyjRekord==wine::RANDOM)
				temp="0";
			else
				if(rekordy[i].CzyjRekord==wine::USER)
					temp="1";
				else
					if(rekordy[i].CzyjRekord==wine::ORYGINAL)
						temp="2";
			str.append(temp);
			str.append(myslnik);


			zapis<<str<<endl;
		}

		return true;
	}

	void DodajRekord(
		float FixedAcidity,
		float VolatileAcidity,
		float CitricAcid,
		float ResidualSugar,
		float Chlorides,
		float FreeSulfurDioxide,
		float TotalSulfurDioxide,
		float Density,
		float pH,
		float Sulphates,
		float Alcohol,
		float Quality,
		wine::ListaTypowKolorow typwina
		)
	{
		wine temp;
		temp.atrybuty[0]=FixedAcidity;
		temp.atrybuty[1]=VolatileAcidity;
		temp.atrybuty[2]=CitricAcid;
		temp.atrybuty[3]=ResidualSugar;
		temp.atrybuty[4]=Chlorides;
		temp.atrybuty[5]=FreeSulfurDioxide;
		temp.atrybuty[6]=TotalSulfurDioxide;
		temp.atrybuty[7]=Density;
		temp.atrybuty[8]=pH;
		temp.atrybuty[9]=Sulphates;
		temp.atrybuty[10]=Alcohol;
		temp.atrybuty[11]=Quality;
		temp.Kolor=typwina;
		temp.CzyjRekord=wine::USER;
		rekordy.push_back(temp);
		BaseReady=true;

	}




	float * operator[](int atr)
	{
		if (BaseReady)
		{


			float *wsk=new float[rekordy.size()];

			for(int i=0;i<rekordy.size();i++)
			{
				wsk[i]=rekordy[i].atrybuty[atr];
			}


			return wsk;

		}else
		{

			throw "Baza nie gotowa do tej operacji\n";
		}
	}
};